package main

/**
* Content: slice声明-初始化方式、切片截取-数组截取、make初始化切片、切片的遍历、append操作、复制切片、删除元素、数组、切片实战
* --------------------------------------------------
* Go slice切片详解和实战: https://juejin.cn/post/7071960543283642404
* Go slice切片详解和实战(make append copy): https://juejin.cn/post/7068573594879524894
* 深入理解 slice: https://juejin.cn/post/7122495050067476510
 */

import "fmt"

func MySlice() {
	// 切片: 相当于可变长度数组，相当于 java 中的 List
	fmt.Println("--------------------slice声明-初始化方式--------------------")

	// 声明切片 -- 未初始化 时为 nil
	var s1 []int // s1 == nil
	var s2 []string
	fmt.Printf("s1==nil: %v, s1==nil: %v\n", s1 == nil, s2 == nil)

	// 声明 并 初始化 - 长度和容量
	var s3 = []int{1, 2, 3}
	fmt.Printf("len(s3): %v, cap(s3): %v\n", len(s3), cap(s3)) // 长度 = 3, 容量 = 3

	// make 初始化切片
	fmt.Println("--------------------make初始化切片--------------------")

	// 初始化长度和容量
	//切片
	ss3 := make([]int, 3, 3) // 开辟空间   [0, 0, 0]
	ss3 = []int{1, 2, 3}     // 引用数组
	ss4 := ss3               // ss4 ss3都指向同一个底层数组
	fmt.Printf("ss4: %v\n", ss4)

	//数组
	aa3 := [3]int{1, 2, 4}
	aa4 := aa3 //数组类型 aa4会开辟新的内存空间
	fmt.Printf("aa4: %v\n", aa4)

	// 切片截取-数组截取  =  得到一个切片
	fmt.Println("--------------------切片截取-数组截取--------------------")

	// 由 数组 得到 切片 (也可由 切片 得到 切片)
	arr1 := [...]int{1, 2, 3, 4, 5}
	s5 := arr1[:]   // 复制数组全部数值
	s6 := arr1[2:4] // 左包含，右不包含
	s7 := arr1[:4]
	s8 := arr1[2:]
	fmt.Printf("s5: %v, s6: %v\n", s5, s6)
	fmt.Printf("s7: %v, s8: %v\n", s7, s8)
	fmt.Printf("len(s6): %v, cap(s6): %v\n", len(s6), cap(s6)) // len(s6): 2, cap(s6): 3

	// 切片的遍历
	fmt.Println("--------------------切片的遍历--------------------")

	s9 := []int{1, 2, 3, 4, 5}
	// 遍历方式1
	for i := 0; i < len(s9); i++ {
		fmt.Printf("s9[%v]: %v--", i, s9[i])
	}
	fmt.Println()
	// 遍历方式2: 更常用的方式
	for i, v := range s9 {
		fmt.Printf("s9[%v]: %v--", i, v)
	}
	fmt.Println()

	// append操作
	fmt.Println("--------------------append操作--------------------")

	// 定义切片
	s10 := []int{11, 12, 13, 14}
	fmt.Printf("s10=%v len(s10)=%d cap(s10)=%d\n", s10, len(s10), cap(s10))

	// 追加一个元素
	s10 = append(s10, 15)
	fmt.Printf("s10=%v len(s10)=%d cap(s10)=%d\n", s10, len(s10), cap(s10))

	// 追加多个元素
	s10_1 := []int{16, 17}
	s10 = append(s10, s10_1...) //...表示拆开，将切片的值作为追加的元素
	fmt.Printf("s10=%v len(s10)=%d cap(s10)=%d\n", s10, len(s10), cap(s10))

	// 复制切片
	fmt.Println("--------------------复制切片--------------------")

	// 定义切片
	s11 := []int{1, 2, 3}

	// 方式1
	var s12 = s11 // 会引用原数组

	// 方式2
	var s13 = make([]int, 3)
	copy(s13, s11) // 会开辟新的内存空间

	// 测试
	s11[0] = 11
	fmt.Printf("s11:%v s12:%v s13:%v\n", s11, s12, s13) //s1和s2是[11 2 3] s3是[1 2 3]

	// 删除元素
	fmt.Println("--------------------删除元素--------------------")

	// 定义切片
	var s15 = []int{1, 2, 3, 4, 5}

	// 删除下标为 1 的元素
	s15 = append(s15[:1], s15[2:]...) // 等价于上面两条语句
	fmt.Printf("s15: %v\n", s15)
}

// 数组、切片实战
func answer2(arr []int, num int) {
	i, j := 0, len(arr)-1
	for i < j {
		if arr[i]+arr[j] == num {
			fmt.Printf("i: %v, j: %v\n", i, j)
			i++
		} else if arr[i]+arr[j] > num {
			j--
		} else {
			i++
		}
	}
}
